package cn.tedu.zhyl.base.interceptors;

import cn.hutool.core.util.StrUtil;
import cn.tedu.zhyl.base.constant.Constants;
import cn.tedu.zhyl.base.response.JsonResult;
import cn.tedu.zhyl.base.response.StatusCode;
import cn.tedu.zhyl.base.utils.AuthContext;
import cn.tedu.zhyl.system.pojo.entity.SysUser;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class LoginAuthInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String method = request.getMethod();
        log.debug("getServletPath:"+request.getServletPath());
        if(method.equalsIgnoreCase("OPTIONS")){
            return true;
        }

        Boolean requestClientIsWx = false;
        String token = request.getHeader(Constants.PC_REQ_HEADER_TOKEN);

        // 未携带token
        if(StrUtil.isEmpty(token)){
            token = request.getHeader(Constants.WX_REQ_HEADER_TOKEN);
            // 如果到这里还没有token，说明既不是pc登录也不是微信登录
            if (StrUtil.isEmpty(token)){
                responseInfo(response,StatusCode.NOT_LOGIN);
                return false;
            }else {
                requestClientIsWx = true;
            }
        }
        // 判断token是否过期
        String redisTokenPrefix = requestClientIsWx ? Constants.WX_USER_LOGIN_API : Constants.USER_LOGIN_API;
        String strUser = redisTemplate.opsForValue().get(redisTokenPrefix + token);
        if(StrUtil.isEmpty(strUser)){
            responseInfo(response,StatusCode.TOKEN_EXPIRED);
            return false;
        }

        // 存入本地线程方便获取
        AuthContext.set(JSON.parseObject(strUser, SysUser.class));

        // 再次刷新token过期时间
        redisTemplate.expire(redisTokenPrefix + token,30, TimeUnit.MINUTES);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        AuthContext.remove();
    }

    private  void responseInfo(HttpServletResponse response, StatusCode statusCode){
        // 构建响应信息
        JsonResult result = JsonResult.build(null, statusCode);

        // 处理中文乱码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");

        // 获取响应流
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.print(JSON.toJSONString(result));

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            writer.close();
        }
    }
}
